package com.way.demo.comm.result;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
* @author lipingwei
* @create 2021-07-05 13:41
 * 参考地址：https://www.cnblogs.com/pxblog/p/13792038.html
*/

@Data
@Accessors(chain = true)
@Builder
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ApiResult<T> implements Serializable {

    private Integer code;
    private String msg;
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime time;
    private T data;

    //构造私有化
    private ApiResult() {
    }

    public static ApiResult result(boolean flag){
        if (flag){
            return ok();
        }
        return fail("");
    }

    public static ApiResult result(ApiCode apiCode){
        return result(apiCode,null);
    }

    public static ApiResult result(ApiCode apiCode,Object data){
        return result(apiCode,null,null,data);
    }

    public static ApiResult result(Integer errCode,String errMsg){
        return  result(null,errCode,errMsg,null);
       }



    public static ApiResult ok(){
        return ok(null);
    }

    public static ApiResult ok(Object data){
        return result(ApiCode.SUCCESS,data);
    }

    public static ApiResult ok(String key,Object value){
        Map<String,Object> map = new HashMap<>();
        map.put(key,value);
        return ok(map);
    }

    /**
     * 返回失败
     * @param apiCode
     * @return
     */
    public static ApiResult fail(ApiCode apiCode){
        return result(apiCode,null);
    }

    public static ApiResult fail(String msg){
        return result(ApiCode.FAIL,null,msg,null);

    }

    public static ApiResult fail(Integer errCode,String errMsg){
        return result(errCode,errMsg);
    }

    /**
     * 返回失败一般，不返回数据，一般不用
     * @param apiCode
     * @param data
     * @return
     */
    private static ApiResult fail(ApiCode apiCode,Object data){
        if (ApiCode.SUCCESS == apiCode){
            throw new RuntimeException("失败结果状态码不能为" + ApiCode.SUCCESS.getCode());
        }
        return result(apiCode,data);

    }

    /**
     * 失败不返回数据，一般不会调用此方法
     * @param key
     * @param value
     * @return
     */
    private static ApiResult fail(String key,Object value){
        Map<String,Object> map = new HashMap<>();
        map.put(key,value);
        return result(ApiCode.FAIL,map);
    }

    /**
     * 核心类私有化，不对外暴露
     * @param apiCode
     * @param errCode
     * @param errMsg
     * @param data
     * @return
     */
    private static ApiResult result(ApiCode apiCode,Integer errCode,String errMsg,Object data){
        String message= StrUtil.isNotBlank(errMsg)?errMsg:apiCode.getMsg();
        Integer code = errCode!=null?errCode:apiCode.getCode();
        return ApiResult.builder()
                .code(code)
                .msg(message)
                .data(data)
                .time(LocalDateTime.now())
                .build();
    }

}

